home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-15  |  18.0 KB  |  786 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     print.c
  4.  
  5.     This module handles printing.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. #include "glob.h"
  15. #include "print.h"
  16. #include "dialog.h"
  17. #include "memutil.h"
  18. #include "newswatcher.h"
  19. #include "dummy.h"
  20. #include "article.h"
  21. #include "strutil.h"
  22. #include "drawutil.h"
  23. #include "ic.h"
  24. #include "resutil.h"
  25.  
  26.  
  27.  
  28. #define kPageSetupInfoResourceType        'NWPS'
  29. #define kPageSetupInfoResourceID        128
  30.  
  31.  
  32.  
  33. /* Globals used for all kinds of printing. */
  34.  
  35. static Boolean gPrintText;        /* true if printing text, false if printing help topic pict */
  36. static THPrint gMyHPrint = nil;    /* printing handle */
  37. static Rect gDrawRect;            /* drawing rectangle */
  38. static short gHalfInch;            /* num pixels in 0.5 inches */
  39. static short gMyRefNum;            /* ref num of NewsWatcher's resource file */
  40. static short gFontNum;            /* font number */
  41. static short gFontSize;            /* font size */
  42. static TEHandle gPrintTE;        /* textedit handle */
  43.  
  44. static PrIdleUPP gIdleProcUPP = nil;
  45.  
  46. /* Globals used for printing picts */
  47.  
  48. static short gPictResID;        /* pict resource id */
  49.  
  50. /* Globals used for printing text */
  51.  
  52. static Handle gText;            /* text to print */
  53. static short gLinesPerPage;        /* # of lines per page */
  54. static long gNumLines;            /* total # lines */
  55.  
  56. /* Globals for printing segmented article windows. */
  57.  
  58. static Boolean gSegmented;            /* true if segmented */
  59. static short gNumSections;            /* number of sections */
  60. static short gCurSection;            /* current section in gPrintTE, or -1 if none */
  61. static long **gSectionBreaks;        /* handle to array of section breaks */
  62. static long **gFirstLines;            /* handle to array of section first line numbers */
  63.  
  64.  
  65.  
  66. /*----------------------------------------------------------------------------
  67.     ReadSavedPageSetupInfoFromPrefs 
  68.     
  69.     Read the save page setup info from the NewsWatcher Prefs file.
  70. ----------------------------------------------------------------------------*/
  71.  
  72. void ReadSavedPageSetupInfoFromPrefs (void)
  73. {
  74.     OSErr err = noErr;
  75.  
  76.     err = MyGet1Resource(kPageSetupInfoResourceType, kPageSetupInfoResourceID, 
  77.         &gMyHPrint);
  78.     if (err == noErr) MyDetachResource(gMyHPrint);
  79. }
  80.  
  81.  
  82.  
  83. /*----------------------------------------------------------------------------
  84.     WritePageSetupInfoToPrefs 
  85.     
  86.     Write the page setup info to the NewsWatcher Prefs file.
  87. ----------------------------------------------------------------------------*/
  88.  
  89. void WritePageSetupInfoToPrefs (void)
  90. {
  91.     if (gMyHPrint != nil) {
  92.         MyReplaceResource(gMyHPrint, kPageSetupInfoResourceType, 
  93.             kPageSetupInfoResourceID, "\p");
  94.     }
  95. }
  96.  
  97.  
  98.  
  99. /*----------------------------------------------------------------------------
  100.     PrepSegements 
  101.     
  102.     Prepare for printing segmented article windows. Calculate the gFirstLines
  103.     array and the total number of lines.
  104. ----------------------------------------------------------------------------*/
  105.  
  106. static void PrepSegmented (void)
  107. {
  108.     long linesInSection,offset,length;
  109.     short i;
  110.     char state;
  111.  
  112.     state = MyHGetState(gText);
  113.     MyHLock(gText);
  114.     for (i = gNumSections-1; i >= 0; i--) {
  115.         offset = (*gSectionBreaks)[i];
  116.         length = (*gSectionBreaks)[i+1] - offset;
  117.         TESetText(*gText+offset,length, gPrintTE);
  118.         (*gFirstLines)[i] = (**gPrintTE).nLines;
  119.     }
  120.     MyHSetState(gText, state);
  121.     
  122.     gNumLines = 0;
  123.     for (i = 0; i < gNumSections; i++) {
  124.         linesInSection = (*gFirstLines)[i];
  125.         (*gFirstLines)[i] = gNumLines;
  126.         gNumLines += linesInSection;
  127.     }
  128.     (*gFirstLines)[gNumSections] = gNumLines;
  129.     gCurSection = 0;
  130. }
  131.  
  132.  
  133.  
  134. /*----------------------------------------------------------------------------
  135.     Prep 
  136.     
  137.     Prepare for printing. Calculate the number of lines per page and the
  138.     total number of pages.
  139.  
  140.     Exit:    function result = error code.
  141. ----------------------------------------------------------------------------*/
  142.  
  143. static OSErr Prep (void)
  144. {
  145.     short numPages;
  146.  
  147.     if (gPrintText) {
  148.         gLinesPerPage = (gDrawRect.bottom - gDrawRect.top) / (**gPrintTE).lineHeight;
  149.         gLinesPerPage -= 8;
  150.         if (gSegmented) {
  151.             PrepSegmented();
  152.         } else {
  153.             gNumLines = (**gPrintTE).nLines;
  154.         }
  155.         numPages = (gNumLines + gLinesPerPage - 1) / gLinesPerPage;
  156.     } else {
  157.         numPages = 1;
  158.     }
  159.     
  160.     if ((**gMyHPrint).prJob.iLstPage > numPages)
  161.         (**gMyHPrint).prJob.iLstPage = numPages;
  162.     if ((**gMyHPrint).prJob.iLstPage < (**gMyHPrint).prJob.iFstPage) {
  163.         ErrorMessageNumber(kStrPrintNoPagesInRange);
  164.         return userCanceledErr;
  165.     }
  166.     return noErr;
  167. }
  168.  
  169.  
  170.  
  171. /*----------------------------------------------------------------------------
  172.     PrintOnePage 
  173.     
  174.     Print one page.
  175.     
  176.     Entry:    pageNum = page number.
  177.             title = title for page header.
  178.  
  179.     Exit:    function result = error code.
  180. ----------------------------------------------------------------------------*/
  181.  
  182. static OSErr PrintOnePage (short pageNum, char *title)
  183. {
  184.     short vCoord;
  185.     long line, lastLine, length;
  186.     long offset = 0;
  187.     long firstLineThisSection = 0;
  188.     long firstLineNextSection;
  189.     short start,next;
  190.     short i;
  191.     char *sectionStart;
  192.     char state;
  193.     short lineHeight;
  194.     Str255 str;
  195.     CStr255 fmt;
  196.     short pageNumWidth, quarterInch, refNum;
  197.     Rect r;
  198.     PicHandle pict;
  199.     Rect dstRect;
  200.     
  201.     TextFont(gFontNum);
  202.     TextSize(gFontSize);
  203.     TextFace(0);
  204.     TextMode(srcCopy);
  205.     
  206.     lineHeight = (**gPrintTE).lineHeight;
  207.     quarterInch = gHalfInch >> 1;
  208.     
  209.     /* Draw the header. */
  210.     
  211.     vCoord = gDrawRect.top + lineHeight + (**gPrintTE).fontAscent;
  212.     sprintf((char*)str, "%d", pageNum);
  213.     c2pstr((char*)str);
  214.     pageNumWidth = StringWidth(str);
  215.     MoveTo(gDrawRect.right - pageNumWidth - quarterInch, vCoord);
  216.     DrawString(str);
  217.     strcpy((char*)str, title);
  218.     c2pstr((char*)str);
  219.     TruncString(gDrawRect.right - gDrawRect.left - pageNumWidth - 2*gHalfInch,
  220.         str, smTruncEnd);
  221.     MoveTo(gDrawRect.left + quarterInch, vCoord);
  222.     DrawString(str);
  223.     SetRect(&r, gDrawRect.left, gDrawRect.top + lineHeight - 4, 
  224.         gDrawRect.right - 2, gDrawRect.top + 2*lineHeight + 5);
  225.     PenPat(&qd.gray);
  226.     PenSize(2, 2);
  227.     FrameRect(&r);
  228.     PenPat(&qd.black);
  229.     PenSize(1, 1);
  230.     
  231.     /* Draw the body of the page (text or pict) */
  232.     
  233.     if (gPrintText) {
  234.         
  235.         state = MyHGetState(gText);
  236.         MyHLock(gText);
  237.         
  238.         line = (pageNum - 1) * gLinesPerPage;
  239.         
  240.         if (line + gLinesPerPage > gNumLines)
  241.             lastLine = gNumLines;
  242.         else
  243.             lastLine = line + gLinesPerPage;
  244.         
  245.         if (gSegmented) {
  246.             for (i = 0; i < gNumSections && line >= (*gFirstLines)[i]; i++) /* do nothing */ ;
  247.             i--;
  248.             offset = (*gSectionBreaks)[i];
  249.             sectionStart = *gText + offset;
  250.             firstLineThisSection = (*gFirstLines)[i];
  251.             firstLineNextSection = (*gFirstLines)[i+1];
  252.             if (i != gCurSection) {
  253.                 length = (*gSectionBreaks)[i+1] - offset;
  254.                 TESetText(sectionStart,length,gPrintTE);
  255.                 gCurSection = i;
  256.             }
  257.         } else {
  258.             sectionStart = *gText;
  259.         }
  260.         
  261.         start = (**gPrintTE).lineStarts[line-firstLineThisSection];
  262.         
  263.         vCoord = gDrawRect.top + 4*lineHeight + (**gPrintTE).fontAscent;
  264.         
  265.         while (true) {
  266.             if (line-firstLineThisSection < (**gPrintTE).nLines-1)
  267.                 next = (**gPrintTE).lineStarts[line+1-firstLineThisSection];
  268.             else
  269.                 next = (**gPrintTE).teLength;
  270.             
  271.             MoveTo(gDrawRect.left, vCoord);
  272.             DrawText(sectionStart, start, next-start);
  273.             line++;
  274.             if (line == lastLine) break;
  275.             
  276.             start = next;
  277.             if (gSegmented && line >= firstLineNextSection) {
  278.                 gCurSection++;
  279.                 offset = (*gSectionBreaks)[gCurSection];
  280.                 sectionStart = *gText + offset;
  281.                 length = (*gSectionBreaks)[gCurSection+1] - offset;
  282.                 TESetText(sectionStart, length, gPrintTE);
  283.                 firstLineThisSection = firstLineNextSection;
  284.                 firstLineNextSection = (*gFirstLines)[gCurSection+1];
  285.                 start = 0;
  286.             }
  287.         
  288.             vCoord += lineHeight;
  289.         }
  290.         
  291.         MyHSetState(gText, state);
  292.         
  293.     } else {
  294.     
  295.         pict = GetPicture(gPictResID);
  296.         HNoPurge((Handle)pict);
  297.         dstRect = (**pict).picFrame;
  298.         OffsetRect(&dstRect, -dstRect.left + gDrawRect.left, 
  299.             -dstRect.top + gDrawRect.top + 4*lineHeight);
  300.         DrawPicture(pict, &dstRect);
  301.         HPurge((Handle)pict);
  302.     
  303.     }
  304.     
  305.     /* Draw the footer. */
  306.     
  307.     vCoord = gDrawRect.bottom - 2*lineHeight + (**gPrintTE).fontAscent;
  308.     refNum = CurResFile();
  309.     UseResFile(gMyRefNum);
  310.     GetCString(kStrPrintedFor, fmt);
  311.     UseResFile(refNum);
  312.     sprintf((char*)str, fmt, gPrefs.emailAddress, gPrefs.fullName);
  313.     c2pstr((char*)str);
  314.     TruncString(gDrawRect.right - gDrawRect.left - 2*gHalfInch,
  315.         str, smTruncEnd);
  316.     MoveTo(gDrawRect.left + quarterInch, vCoord);
  317.     DrawString(str);
  318.     SetRect(&r, gDrawRect.left, gDrawRect.bottom - 2*lineHeight - 4, 
  319.         gDrawRect.right - 2, gDrawRect.bottom - lineHeight + 5);
  320.     PenPat(&qd.gray);
  321.     PenSize(2, 2);
  322.     FrameRect(&r);
  323.     PenPat(&qd.black);
  324.     PenSize(1, 1);
  325.     
  326.     return noErr;
  327. }
  328.  
  329.  
  330.  
  331. /*----------------------------------------------------------------------------
  332.     IdleProc 
  333.     
  334.     The printing idle proc.
  335. ----------------------------------------------------------------------------*/
  336.  
  337. static pascal void IdleProc (void)
  338. {
  339.     OSErr err = noErr;
  340.     short refNum;
  341.  
  342.     refNum = CurResFile();
  343.     UseResFile(gMyRefNum);
  344.     err = GiveTime(true);
  345.     UseResFile(refNum);
  346.     if (err != noErr) PrSetError(iPrAbort);
  347. }
  348.  
  349.  
  350.  
  351. /*----------------------------------------------------------------------------
  352.     PrintTheDoc 
  353.     
  354.     Print the document.
  355.     
  356.     Entry:    title = title for page headers, and print job name
  357.  
  358.     Exit:    function result = error code.
  359. ----------------------------------------------------------------------------*/
  360.  
  361. static OSErr PrintTheDoc (char *title)
  362. {
  363.     short theFirst, theLast;
  364.     short nCopies;
  365.     short prDevice;
  366.     Boolean draftMode;
  367.     TPrStatus prStatus;
  368.     GrafPtr port;
  369.     OSErr err = noErr;
  370.     short i, p;
  371.     TPPrPort prPort;
  372.     Boolean prIsOpen = false;
  373.     Boolean docIsOpen = false;
  374.     Boolean pageIsOpen = false;
  375.     
  376.     MyICReadSharedPrefs(kICRealName);
  377.     MyICReadSharedPrefs(kICEmail);
  378.  
  379.     GetPort(&port);
  380.     PrOpen();
  381.     err = PrError();
  382.     if (err != noErr) goto exit;
  383.     prIsOpen = true;
  384.     
  385.     err = ShowDummyWindow();
  386.     if (err != noErr) goto exit;
  387.     c2pstr(title);
  388.     SetWTitle(FrontWindow(), (StringPtr)title);
  389.     p2cstr((StringPtr)title);
  390.  
  391.     PrValidate(gMyHPrint);
  392.     err = PrError();
  393.     if (err != noErr) goto exit;
  394.     err = Prep();
  395.     if (err != noErr) goto exit;
  396.     theFirst = (**gMyHPrint).prJob.iFstPage;
  397.     theLast = (**gMyHPrint).prJob.iLstPage;
  398.     (**gMyHPrint).prJob.iFstPage = 1;
  399.     (**gMyHPrint).prJob.iLstPage = 9999;
  400.     prDevice = ((**gMyHPrint).prStl.wDev >> 8);
  401.     draftMode = (((**gMyHPrint).prJob.bJDocLoop) & 1) == 0;
  402.     if ((draftMode) && (prDevice == 1))
  403.         nCopies = (**gMyHPrint).prJob.iCopies;
  404.     else
  405.         nCopies = 1;
  406.     prPort = PrOpenDoc(gMyHPrint, nil, nil);
  407.     err = PrError();
  408.     if (err != noErr) goto exit;
  409.     docIsOpen = true;
  410.     
  411.     HideDummyWindow();
  412.     
  413.     SetPort(&prPort->gPort);
  414.     for (i=1; i <= nCopies; i++) {
  415.         for (p = theFirst; p <= theLast; p++) {
  416.             PrOpenPage(prPort, nil);
  417.             err = PrError();
  418.             if (err != noErr) goto exit;
  419.             pageIsOpen = true;
  420.             err = PrintOnePage(p, title);
  421.             if (err != noErr) goto exit;
  422.             PrClosePage(prPort);
  423.             err = PrError();
  424.             if (err != noErr) goto exit;
  425.             pageIsOpen = false;
  426.         }
  427.     }
  428.     PrCloseDoc(prPort);
  429.     err = PrError();
  430.     if (err != noErr) goto exit;
  431.     docIsOpen = false;
  432.     
  433.     if (!draftMode) {
  434.         PrPicFile(gMyHPrint, nil, nil, nil, &prStatus);
  435.         err = PrError();
  436.         if (err != noErr) goto exit;
  437.     }
  438.  
  439.     PrClose();
  440.     err = PrError();
  441.     if (err != noErr) goto exit;
  442.     prIsOpen = false;
  443.     
  444.     (**gMyHPrint).prJob.iFstPage = theFirst;
  445.     (**gMyHPrint).prJob.iLstPage = theLast;
  446.     
  447.     SetPort(port);
  448.     return noErr;
  449.     
  450. exit:
  451.  
  452.     HideDummyWindow();
  453.     SetPort(port);
  454.     if (pageIsOpen) PrClosePage(prPort);
  455.     if (docIsOpen) PrCloseDoc(prPort);
  456.     if (prIsOpen) PrClose();
  457.     return err;
  458. }
  459.  
  460.  
  461.  
  462. /*----------------------------------------------------------------------------
  463.     InitPrint 
  464.     
  465.     Intialize printing.
  466.  
  467.     Exit:    function result = error code.
  468. ----------------------------------------------------------------------------*/
  469.  
  470. static OSErr InitPrint (void)
  471. {
  472.     OSErr err = noErr;
  473.  
  474.     if (gMyHPrint != nil) return noErr;
  475.     PrOpen();
  476.     err = PrError();
  477.     if (err != noErr) return err;
  478.     err = MyNewHandle(sizeof(TPrint), &gMyHPrint);
  479.     if (err != noErr) goto exit;
  480.     PrintDefault(gMyHPrint);
  481.     err = PrError();
  482.     if (err != noErr) goto exit;
  483.     PrClose();
  484.     return PrError();
  485.     
  486. exit:
  487.  
  488.     PrClose();
  489.     return err;
  490. }
  491.  
  492.  
  493.  
  494. /*----------------------------------------------------------------------------
  495.     PrintError 
  496.     
  497.     Handle a printing error.
  498.     
  499.     Entry:    err = error code.
  500.  
  501.     Exit:    function result = error code.
  502. ----------------------------------------------------------------------------*/
  503.  
  504. static OSErr PrintError (OSErr err)
  505. {
  506.     if (err == fnfErr) {
  507.         ErrorMessageNumber(kStrPrintNoDriver);
  508.         return userCanceledErr;
  509.     } else if (err == resNotFound) {
  510.         ErrorMessageNumber(kStrNoPrinterSelected);
  511.         return userCanceledErr;
  512.     } else {
  513.         return err;
  514.     }
  515. }
  516.  
  517.  
  518.  
  519. /*----------------------------------------------------------------------------
  520.     DoPageSetup 
  521.     
  522.     Handle the "Page Setup" command.
  523.  
  524.     Exit:    function result = error code.
  525. ----------------------------------------------------------------------------*/
  526.  
  527. OSErr DoPageSetup (void)
  528. {
  529.     OSErr err = noErr;
  530.     Boolean prIsOpen = false;
  531.     
  532.     err = InitPrint();
  533.     if (err != noErr) goto exit;
  534.     InitCursor();
  535.     PrOpen();
  536.     err = PrError();
  537.     if (err != noErr) goto exit;
  538.     prIsOpen = true;
  539.     PrValidate(gMyHPrint);
  540.     err = PrError();
  541.     if (err != noErr) goto exit;
  542.     PrepUserInteraction();
  543.     PrStlDialog(gMyHPrint);
  544.     err = PrError();
  545.     if (err != noErr) goto exit;
  546.     PrClose();
  547.     err = PrError();
  548.     if (err != noErr) goto exit;
  549.     return noErr;
  550.     
  551. exit:
  552.  
  553.     if (prIsOpen) PrClose();
  554.     return PrintError(err);
  555. }
  556.  
  557.  
  558.  
  559. /*----------------------------------------------------------------------------
  560.     StartPrint 
  561.     
  562.     Present the print job dialog.
  563.  
  564.     Exit:    function result = error code.
  565. ----------------------------------------------------------------------------*/
  566.  
  567. OSErr StartPrint (void)
  568. {
  569.     Boolean result;
  570.     GrafPtr port;
  571.     OSErr err = noErr;
  572.     Boolean prIsOpen = false;
  573.     short i;
  574.  
  575.     GetPort(&port);
  576.     gMyRefNum = CurResFile();
  577.     err = InitPrint();
  578.     if (err != noErr) goto exit;
  579.     PrOpen();
  580.     err = PrError();
  581.     if (err != noErr) goto exit;
  582.     prIsOpen = true;
  583.     PrValidate(gMyHPrint);
  584.     err = PrError();
  585.     if (err != noErr) goto exit;
  586.     InitCursor();
  587.     err = PrepUserInteraction();
  588.     if (err == noErr) {
  589.         result = PrJobDialog(gMyHPrint);
  590.         err = PrError();
  591.         if (err != noErr) goto exit;
  592.         if (!result) {
  593.             err = userCanceledErr;
  594.             goto exit;
  595.         }
  596.     } else if (err == errAENoUserInteraction) {
  597.         PrintDefault(gMyHPrint);
  598.         err = noErr;
  599.     } else {
  600.         goto exit;
  601.     }
  602.     (**gMyHPrint).prJob.pIdleProc = gIdleProcUPP;
  603.  
  604.     PrClose();
  605.     err = PrError();
  606.     if (err != noErr) goto exit;
  607.     prIsOpen = false;
  608.     
  609.     for (i = 0; i < 10; i++) {
  610.         err = GiveTime(true);
  611.         if (err != noErr) goto exit;
  612.     }
  613.     
  614.     SetPort(port);
  615.     return noErr;
  616.     
  617. exit:
  618.  
  619.     SetPort(port);
  620.     if (prIsOpen) PrClose();
  621.     return PrintError(err);
  622. }
  623.  
  624.  
  625.  
  626. /*----------------------------------------------------------------------------
  627.     PrintText 
  628.     
  629.     Print text.
  630.     
  631.     Entry:    text = handle to text to be printed.
  632.             start = offset in text of beginning of text to be printed.
  633.             end = offset in text of end of text to be printed.
  634.             title = title for page headers, and print job name
  635.  
  636.     Exit:    function result = error code.
  637. ----------------------------------------------------------------------------*/
  638.  
  639. OSErr PrintText (Handle text, long start, long end, char *title)
  640. {
  641.     Handle oldText;
  642.     OSErr err = noErr;
  643.     long len;
  644.     Boolean disposeText = false;
  645.     short iFstPage, iLstPage;
  646.     TextStyle style;
  647.     
  648.     gPrintText = true;
  649.     
  650.     MyICReadSharedPrefs(kICPrinterFont);
  651.     
  652.     gText = nil;
  653.     gPrintTE = nil;
  654.     gFirstLines = nil;
  655.     gSectionBreaks = nil;
  656.     
  657.     if (!MemoryAvailable(50000L)) return memFullErr;
  658.  
  659.     err = InitPrint();
  660.     if (err != noErr) return err;
  661.     
  662.     InitCursor();
  663.         
  664.     gDrawRect = (**gMyHPrint).prInfo.rPage;
  665.     gHalfInch = (**gMyHPrint).prInfo.iHRes >> 1;
  666.     gDrawRect.left += gHalfInch;
  667.     gDrawRect.right -= gHalfInch;
  668.     
  669.     GetFontNumber(gPrefs.printingFont, &gFontNum);
  670.     gFontSize = gPrefs.printingSize;
  671.     GetPortTextStyle(&style);
  672.     TextFont(gFontNum);
  673.     TextSize(gFontSize);
  674.     gPrintTE = TENew(&gDrawRect, &gDrawRect);
  675.     SetPortTextStyle(&style);
  676.  
  677.     len = MyGetHandleSize(text);
  678.     if (start > 0 || end < len) {
  679.         len = end - start;
  680.         err = MyNewHandle(len, &gText);
  681.         if (err != noErr) goto exit;
  682.         disposeText = true;
  683.         BlockMoveData(*text + start, *gText, len);
  684.     } else {
  685.         gText = text;
  686.     }
  687.     
  688.     if (len > 0x7fff) {
  689.         gSegmented = true;
  690.         err = MakeSections(gText, &gSectionBreaks, &gNumSections);
  691.         if (err != noErr) goto exit;
  692.         gCurSection = -1;
  693.         err = MyNewHandle(sizeof(long) * (gNumSections+1), &gFirstLines);
  694.         if (err != noErr) goto exit;
  695.     } else {
  696.         gSegmented = false;
  697.         oldText = (**gPrintTE).hText;
  698.         (**gPrintTE).hText = gText;
  699.         TECalText(gPrintTE);
  700.     }
  701.     
  702.     iFstPage = (**gMyHPrint).prJob.iFstPage;
  703.     iLstPage = (**gMyHPrint).prJob.iLstPage;
  704.     err = PrintTheDoc(title);
  705.     (**gMyHPrint).prJob.iFstPage = iFstPage;
  706.     (**gMyHPrint).prJob.iLstPage = iLstPage;
  707.     
  708. exit:
  709.  
  710.     if (disposeText) MyDisposeHandle(gText);
  711.     MyDisposeHandle(gFirstLines);
  712.     MyDisposeHandle(gSectionBreaks);
  713.     if (gPrintTE != nil) {
  714.         if (!gSegmented) (**gPrintTE).hText = oldText;
  715.         TEDispose(gPrintTE);
  716.     }
  717.     
  718.     return err;
  719. }
  720.  
  721.  
  722.  
  723. /*----------------------------------------------------------------------------
  724.     PrintPict 
  725.     
  726.     Print a help topic pict.
  727.     
  728.     Entry:    pictResID = pict resource id.
  729.             title = title for page headers, and print job name
  730.  
  731.     Exit:    function result = error code.
  732. ----------------------------------------------------------------------------*/
  733.  
  734. OSErr PrintPict (short pictResID, char *title)
  735. {
  736.     OSErr err = noErr;
  737.     short iFstPage, iLstPage;
  738.     TextStyle style;
  739.     
  740.     gPrintText = false;
  741.     gPictResID = pictResID;
  742.     
  743.     MyICReadSharedPrefs(kICPrinterFont);
  744.     
  745.     if (!MemoryAvailable(50000L)) return memFullErr;
  746.  
  747.     err = InitPrint();
  748.     if (err != noErr) return err;
  749.     
  750.     InitCursor();
  751.         
  752.     gDrawRect = (**gMyHPrint).prInfo.rPage;
  753.     gHalfInch = (**gMyHPrint).prInfo.iHRes >> 1;
  754.     gDrawRect.left += gHalfInch;
  755.     gDrawRect.right -= gHalfInch;
  756.     
  757.     GetFontNumber(gPrefs.printingFont, &gFontNum);
  758.     gFontSize = gPrefs.printingSize;
  759.     GetPortTextStyle(&style);
  760.     TextFont(gFontNum);
  761.     TextSize(gFontSize);
  762.     gPrintTE = TENew(&gDrawRect, &gDrawRect);
  763.     SetPortTextStyle(&style);
  764.     
  765.     iFstPage = (**gMyHPrint).prJob.iFstPage;
  766.     iLstPage = (**gMyHPrint).prJob.iLstPage;
  767.     err = PrintTheDoc(title);
  768.     (**gMyHPrint).prJob.iFstPage = iFstPage;
  769.     (**gMyHPrint).prJob.iLstPage = iLstPage;
  770.     
  771.     return noErr;
  772. }
  773.  
  774.  
  775.  
  776. /*----------------------------------------------------------------------------
  777.     print_InitUPP
  778.     
  779.     Initialize UPPs.
  780. ----------------------------------------------------------------------------*/
  781.  
  782. void print_InitUPP (void)
  783. {
  784.     gIdleProcUPP = NewPrIdleProc(IdleProc);
  785. }
  786.